/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.metadata.rtcustomization.api;

import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.Metadata4Ref;
import com.inspur.edp.lcm.metadata.api.entity.MetadataHeader;
import com.inspur.edp.lcm.metadata.api.entity.ServiceUnitInfo;
import com.inspur.edp.metadata.rtcustomization.api.entity.ChangeMetadataSourceTypeInfo;
import com.inspur.edp.metadata.rtcustomization.api.entity.ChangeMetadataSourceTypeResponse;
import com.inspur.edp.metadata.rtcustomization.api.entity.DimensionExtendEntity;
import com.inspur.edp.metadata.rtcustomization.api.entity.MetadataFilter;

import java.io.File;
import java.util.List;

/**
 * 元数据{@link GspMetadata}运行时增删改查接口。
 *
 * <p>供外部调用。是rpc客户端接口，支持拆su环境使用。</p>
 *
 * <p>这个类包含了获取运行时元数据实体的接口，包括国际化和非国际化，包括各种类型已发布的元数据。
 * 还包含了获取运行时元数据列表的接口，以及运行时元数据的su信息{@link ServiceUnitInfo}。
 * 这个类支持元数据包入库、预加载元数据、清除指定元数据的缓存功能。</p>
 *
 * @author liangff
 * @author zhaoleitr
 * @author Lee
 * @author sun
 * @version 0.1.24
 */
public interface CustomizationRtService {

    /**
     * 运行时根据元数据id获取元数据
     *
     * <p>根据元数据uuid，从缓存中获取元数据实体。如果缓存中不存在，则调用rpc服务去rpc服务端获取元数据实体，rpc服务端将从缓存或者数据库中获取元数据实体。
     * Deprecated As of metadata-rtcustomization-api version 0.1.28, replaced by CustomizationService#getGspMetadata(com.inspur.edp.metadata.rtcustomization.api.entity.MetadataQueryParam).</p>
     *
     * @param metadataId 元数据id，uuid，不可为null
     * @return 元数据实体
     */
    @Deprecated
    GspMetadata getMetadata(String metadataId);

    /**
     * 运行时根据元数据id和是否国际化获取元数据实体。
     *
     * <p>需要传递元数据uuid和是否国际化。如果{@code isI18n == true}，则调用{@code getMetadata(String metadataId)}。
     * 否则从缓存中获取非国际化元数据，或者从rpc服务端获取元数据字符串，然后反序列化为元数据实体。
     * Deprecated As of metadata-rtcustomization-api version 0.1.28, replaced by CustomizationService#getGspMetadata(com.inspur.edp.metadata.rtcustomization.api.entity.MetadataQueryParam).</p>
     *
     * @param metadataId 元数据id
     * @param isI18n 是否国际化
     * @return 元数据实体
     */
    @Deprecated
    GspMetadata getMetadata(String metadataId, boolean isI18n);

    /**
     * 获取指定类型的运行时定制元数据
     *
     * Deprecated As of metadata-rtcustomization-api version 0.1.28, replaced by CustomizationService#getMetadataList(com.inspur.edp.metadata.rtcustomization.api.entity.Metadata4RefQueryParam).
     *
     * @param metadataTypes 元数据类型列表
     * @return 元数据信息列表
     */
    @Deprecated
    List<Metadata4Ref> getAllCustomizedRtMetadataInfo(List<String> metadataTypes);

    /**
     * 根据扩展元数据获取被扩展的元数据
     *
     * @param metadataId 元数据id
     * @param certId     证书id
     * @return 元数据实体
     */
    List<DimensionExtendEntity> getExtMdByBasicMdId(String metadataId, String certId);

    /**
     * 预加载元数据
     *
     * <p>根据指定条件预加载元数据，需要传递过滤器{@link MetadataFilter}。bef组在使用。在rpc服务端处理。</p>
     *
     * @param metadataFilter 为null则不进行过滤。其中包括suCodes,metadataTypes,processModes，均为list，为null则不过滤。
     */
    void preloadMetadata(MetadataFilter metadataFilter);

    /**
     * 获取指定的元数据列表
     *
     * <p>获取元数据列表需要传递过滤器{@link MetadataFilter}。获取的列表只有元数据头部信息，可以继续使用{@code getMetadata(String metadataId)}来获取元数据实体。
     * TODO 目前过滤器中仍缺少sourceType为generated等类型的元数据列表，需要增加。并且需要增加“或”连接方式。</p>
     *
     * @param metadataFilters 为null则不进行过滤。其中包括suCodes,metadataTypes,processModes，均为list，为null则不过滤。
     * @return 元数据列表
     */
    List<Metadata4Ref> getMetadataListByFilters(List<MetadataFilter> metadataFilters);

    /**
     * 过滤获取所有元数据
     *
     * @param metadataFilter 为null则不进行过滤。其中包括suCodes,metadataTypes,processModes，均为list，为null则不过滤。
     * @return 元数据列表
     */
    List<Metadata4Ref> getMetadataListByFilter(MetadataFilter metadataFilter);

    /**
     * 将元数据包信息和元数据信息更新到数据库中
     *
     * <p>将指定的元数据包入库，需要元数据包文件。元数据包文件中包含元数据包信息和元数据实体信息，元数据包信息将会存入gspmdpkg表中，元数据实体信息存入gspmdrtcontent表中。
     * 元数据入库流程中将先删除旧的元数据包信息和元数据实体，然后存入新的元数据包信息和实体。在删除元数据时会触发元数据删除后事件，在存入元数据实体前后会触发元数据入库前后扩展。这些事件和扩展有bef使用。</p>
     *
     * @param mdpkg 元数据包文件
     */
    void saveMdpkg(File mdpkg);

    /**
     * 根据元数据ID获取SU信息
     *
     * <p>需传递元数据uuid作为参数。在服务启动时，启动后事件中会将元数据包中的元数据的su信息获取到，存入缓存中。元数据更新的时候，缓存会同时更新。
     * 此方法会先去缓存中获取此元数据的su信息，基本上缓存中都会有，不存在缓存中不存在的情况。如果缓存中不存在，则会从gspmdrtcontent表中获取此元数据所在的元数据包信息，
     * 然后从gspmdpkg表中获取su信息。</p>
     *
     * @param metadataId 元数据ID
     * @return 元数据所属SU信息
     */
    ServiceUnitInfo getServiceUnitInfo(String metadataId);

    /**
     * 根据元数据uuid列表删除其缓存
     *
     * <p>删除缓存需要传递元数据uuid列表。删除缓存时会遍历uuid列表，然后遍历国际化语言表删除各个国际化的缓存，也删除非国际化的缓存。同时删除设计时的缓存。</p>
     *
     * @param metadataIds 待删除的元数据uuid集合
     * @author sunhongfei01
     * @since 2021-7-20
     */
    void removeCacheByMetadataIds(List<String> metadataIds);

    /**
     * 根据引用的元数据id查找引用此元数据的元数据列表
     * @param metadataId
     * @return 引用此元数据的元数据列表，仅有头部信息
     */
    List<MetadataHeader> getMetadatasByRefedMetadataId(String metadataId);

    /**
     * 根据引用的元数据id查找引用此元数据的元数据列表
     * @param metadataId
     * @param metadataTypes 元数据类型列表，类型为lcm_metadataextend中的类型，如GSPBusinessEntity
     * @return 引用此元数据的元数据列表，仅有头部信息
     */
    List<MetadataHeader> getMetadatasByRefedMetadataId(String metadataId, List<String> metadataTypes);

    /**
     * 获取元数据包信息，带有来源类型（包里的、运行时生成的、运行时定制的、零代码的）
     * 如果元数据是包元数据，则返回元数据包信息，不带content
     * 如果元数据是包元数据，但是缺少包信息，则抛异常
     * 如果元数据不是包元数据，是运行时定制发布的元数据，或者是零代码发布的元数据，或者是运行时生成的元数据，则返回Metadata4Ref，但是其中的MetadataPackageHeader是空
     * 如果元数据不存在，则返回null
     * 当前给低零代码融合使用，零代码转成低代码工程时，根据元数据依赖关系，给工程添加数据库引用，需要使用这个接口获取包信息和引用类型
     * @param metadataId		元数据id
     * @return Metadata4Ref     元数据包信息，不带元数据包信息的Metadata4Ref，或者null
     */
    Metadata4Ref getMetadata4RefWithSourceType(String metadataId);

    /**
     * 将已发布的包元数据的类型修改为指定类型，并将元数据包信息删除，包括gspmdpkg中的信息和元数据上的mdpkgid信息。
     * @param changeInfos 元数据类型转换参数列表
     * @return ChangeMetadataSourceTypeResponse 元数据类型转换响应信息
     */
    ChangeMetadataSourceTypeResponse changeMetadataSourceType(List<ChangeMetadataSourceTypeInfo> changeInfos);
}
